package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import com.aliyuncs.utils.StringUtils;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.model.domain.PageResult;
import com.tanhua.model.domain.mongo.FocusUser;
import com.tanhua.model.domain.mongo.Video;
import com.tanhua.model.domain.mysql.UserInfo;
import com.tanhua.model.domain.vo.VideoVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.exception.ErrorResult;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lk
 * @date 2022-04-03
 */
@Service
public class SmallVideoService {
    @DubboReference
    private VideoApi videoApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer webServer;

    //发小视频
    public void saveVideos(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        if (videoThumbnail.isEmpty() || videoFile.isEmpty()) {
            throw new BusinessException(ErrorResult.error());
        }
        //获取文件名后缀
        String videoFilename = videoFile.getOriginalFilename();   //例:ssss.MP4
        String videoSufix = videoFilename.substring(videoFilename.lastIndexOf(".") + 1);  //例: MP4
        //上传视频文件                                    文件输入流                   文件长度               文件后缀     元数据
        StorePath videoPath = storageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), videoSufix, null);
        //下载获取路径
        String videoUrl = webServer.getWebServerUrl() + videoPath.getFullPath();

        String picFilename = videoThumbnail.getOriginalFilename();
        String picSufix = picFilename.substring(picFilename.lastIndexOf(".") + 1);
        StorePath picPath = storageClient.uploadFile(videoThumbnail.getInputStream(), videoThumbnail.getSize(), picSufix, null);
        String picUrl = webServer.getWebServerUrl() + picPath;

        //创建保存对象
        Video video = new Video();
        video.setPicUrl(picUrl);
        video.setId(ObjectId.get());
        video.setVideoUrl(videoUrl);
        video.setText("我是真的爱JAVA");
        video.setUserId(UserHolder.getUserId());
        video.setCreated(System.currentTimeMillis());
        videoApi.save(video);

    }

    //视频列表
    @Cacheable(value = "videos",
            key = "T(com.tanhua.server.interceptor.UserHolder)" +
            ".getUserId()+'_'+#page+'_'+#pagesize")
    public PageResult queryVideoList(Integer page, Integer pagesize) {
        //查询redis数据
        String redisKey = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);

        List<Video> videoList = new ArrayList<>();
        //记录redis里面的数据有几页
        int redisPage = 0;
        //判断redis数据是否存在,判断数据是否满足本次分页条数
        if (!StringUtils.isEmpty(redisKey)) {
            String[] split = redisValue.split(",");
            //判断当前页的起始条数是否小于数组总数
            if ((page - 1) * pagesize < split.length) {
                List<Long> collect = Arrays.stream(split).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e -> Long.valueOf(e))
                        .collect(Collectors.toList());
               videoList = videoApi.findVideo(collect);
            }
            //查询redis中有几页数据
            redisPage = PageUtil.totalPage(split.length,pagesize);
        }
        //如果redis数据不存在,分页查询视频数据
        if (videoList.isEmpty()){
            videoList = videoApi.queryVideoList(page - redisPage,pagesize);
        }

        List<Long> userIds = CollUtil.getFieldValues(videoList, "userId", Long.class);
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(userIds, null);
        //构造返回值
        List<VideoVo> vos = new ArrayList<>();
        for (Video video : videoList) {
            UserInfo userInfo = infoMap.get(video.getUserId());
            if (userInfo != null){
                VideoVo init = VideoVo.init(userInfo, video);
                vos.add(init);
            }
        }
        return new PageResult(page,pagesize,0,vos);
    }

    //关注视频作者
    public void userFocus(Long followUserId) {
        //设置需要保存进数据库的对象
        FocusUser focusUser = new FocusUser();
        focusUser.setUserId(UserHolder.getUserId());
        focusUser.setFollowUserId(followUserId);
        focusUser.setCreated(System.currentTimeMillis());
        videoApi.saveFollowUser(focusUser);
        //将关注记录存入redis中
        String key = Constants.FOCUS_USER;
        String hashKey = UserHolder.getUserId().toString()+followUserId;
        redisTemplate.opsForHash().put(key, hashKey, "1");
    }

    // 取消关注视频作者
    public void userUnFocus(Long followUserId) {
        videoApi.deleteFollowUser(followUserId,UserHolder.getUserId());
        //删除redis缓存
        String key = Constants.FOCUS_USER;
        String hashKey =UserHolder.getUserId().toString()+followUserId;
        redisTemplate.opsForHash().delete(key, hashKey);
    }
}
